#import sys
#import os
#import time
#import threading
import cv2
#import pyprind
from PIL import Image

# 基类
class CharFrame:

    ascii_char = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "

    # 像素映射到字符
    def pixelToChar(self, luminance):
        return self.ascii_char[int(luminance/256*len(self.ascii_char))]

    # 将普通帧转为 ASCII 字符帧
    # limitSize 参数接受一个元组，表示图片的限宽限高。
    # fill 表示是否用空格填充图片宽度至限宽，wrap 表示是否在行末添加换行符
    def convert(self, img, limitSize=-1, fill=False, wrap=False):
        if limitSize != -1 and (img.shape[0] > limitSize[1] or img.shape[1] > limitSize[0]):
            img = cv2.resize(img, limitSize, interpolation=cv2.INTER_AREA)
        ascii_frame = ''
        blank = ''
        if fill:
            blank += ' '*(limitSize[0]-img.shape[1])
        if wrap:
            blank += '\n'
        for i in range(img.shape[0]): # shape 为元组 图片的（宽，高）
            for j in range(img.shape[1]):
                ascii_frame += self.pixelToChar(img[i,j])
            ascii_frame += blank
        return ascii_frame


'''
    图片转字符画

'''
class I2Char(CharFrame):

    result = None
    def __init__(self, path, limitSize=-1):
        self.genCharImage(path, limitSize)

    def loadImage(self, path, limitSize):
        # 1. open image
        try:
            img = Image.open(path)
        except:
            print("Error: Can not open the image file!")
            raise FileNotFoundError

        #2 resize
        if limitSize != -1:
            img = img.resize((limitSize[1],limitSize[0]), Image.NEAREST)

        #Convert RGB image to Gray mode
        return img.convert("L")


    def genCharImage(self, path, limitSize=-1):
        img = self.loadImage(path, limitSize)

        # 调用 CharFrame.pixelToChar() 转成对应的字符
        self.result = ""
        for i in range(img.size[1]):
            for j in range(img.size[0]):
                self.result += self.pixelToChar(img.getpixel((j, i)))
            self.result += '\n'

        return

    # 将字符画写入txt文件
    def export(self, filepath):
        if not self.result:
            return
        with open(filepath,'w') as f:
            f.write(self.result)

    # 从txt中导入字符动画，方便播放
    def load(self, filepath):
        with open(filepath, 'r') as f:
            self.result = f.read()

    def show(self):
        pass

if __name__ == '__main__':
    import argparse
    # 设置命令行参数
    parser = argparse.ArgumentParser()
    parser.add_argument('file')  # 输入文件 必要参数
    parser.add_argument('-o', '--output')  # 输出文件 可选参数
    parser.add_argument('--width', type=int, default=80)  # 输出字符画宽 缺省参数
    parser.add_argument('--height', type=int, default=80)  # 输出字符画高

    # 获取参数
    args = parser.parse_args()

    '''
        通过命令行调用图片转字符画功能 ,命令行执行 Python v2char.py t3.jpeg,输出字符画
    '''
    i2char = I2Char(args.file, [args.height, args.width])

    if args.output:
        with open(args.output, 'w') as f:
            f.write(i2char.result)
    else:
        with open("output.txt", 'w') as f:
            f.write(i2char.result)

    print(i2char.result)

